package com.zhuanzhuan.hero.user.recent.assembler;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.bj58.youpin.common.utils.json.JsonUtils;
import com.google.common.collect.Maps;
import com.zhuanzhuan.hero.user.consts.NumConsts;
import com.zhuanzhuan.hero.user.enums.LabelAuthOperateTypeEnum;
import com.zhuanzhuan.hero.user.enums.LabelTypeEnum;
import com.zhuanzhuan.hero.user.enums.RecentDataEnum;
import com.zhuanzhuan.hero.user.recent.assembler.base.RecentMsgAssembleContext;
import com.zhuanzhuan.hero.user.recent.assembler.base.UserRecentMsgAssembler;
import com.zhuanzhuan.hero.user.service.HeroUserLabelAuthRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author jiazebiao
 * @date 2024/7/11
 * @description 最近认证
 */
@Component
@Slf4j
public class FellowCertificateMsgAssembler implements UserRecentMsgAssembler {

    private static final String FORMAT = "近%s天有%s人认证用户";

    @Resource
    private HeroUserLabelAuthRecordService userLabelAuthRecordService;

    @Override
    public Map<Long, EnumMap<RecentDataEnum, String>> assemble(RecentMsgAssembleContext context) {
        log.info("FellowCertificateMsgAssembler.assemble param={}", JsonUtils.toJsonWithoutNull(context));
        Map<Long, String> userAuthMsgMap = fraternityAuthUpdates(context.getUids());
        log.info("FellowCertificateMsgAssembler.assemble result={}", JsonUtils.toJsonWithoutNull(userAuthMsgMap));
        if(MapUtils.isEmpty(userAuthMsgMap)){
            return Maps.newHashMap();
        }
        Map<Long, EnumMap<RecentDataEnum, String>> rst = Maps.newHashMap();
        userAuthMsgMap.forEach((uid, recentMsg) -> {
            if (StringUtils.isNotBlank(recentMsg)) {
                EnumMap<RecentDataEnum, String> map = Maps.newEnumMap(RecentDataEnum.class);
                map.put(RecentDataEnum.FELLOW_CERTIFICATE_COUNT, recentMsg);
                rst.put(uid, map);
            }
        });
        return rst;
    }

    private Map<Long, String> fraternityAuthUpdates(List<Long> uids) {
        Map<Long, String> uidMsgMap = new HashMap<>();
        Date now = new Date();

        List<Long> needStatisticUid;

        //5天内的
        needStatisticUid = this.statisticUidAuthNum(now, NumConsts.FIVE, uids, uidMsgMap);

        //7天内的
        if (CollectionUtils.isNotEmpty(needStatisticUid)) {
            needStatisticUid = this.statisticUidAuthNum(now, NumConsts.SEVEN, needStatisticUid, uidMsgMap);
        }

        //14天内的
        if (CollectionUtils.isNotEmpty(needStatisticUid)) {
            this.statisticUidAuthNum(now, NumConsts.FOURTRRN, needStatisticUid, uidMsgMap);
        }

        return uidMsgMap;
    }

    /**
     * 查询统计用户的被认证数并赋值给uidMsgMap
     *
     * @param now 初十时间
     * @param diffDay 间隔天数
     * @param uids 要查询的用户
     * @param uidMsgMap 结果装配
     * @return java.util.List<java.lang.Long>
     * @author  hanjunjun
     * @date 2024/7/29
     **/
    private List<Long> statisticUidAuthNum(Date now, Integer diffDay, List<Long> uids, Map<Long, String> uidMsgMap) {
        List<Long> absentAuthNumUid = new ArrayList<>();
        DateTime visitTimeStart = DateUtil.offsetDay(now, -diffDay);
        //查询用户对应的被认证数   k:uid v:authNum
        Map<Long, Integer> uidAuthNumMap =
            userLabelAuthRecordService.queryUidAuthNum(uids, LabelTypeEnum.FRATERNITY_AUTH.getCode(),
                LabelAuthOperateTypeEnum.AUTH.getCode(), visitTimeStart);
        uids.forEach(uid -> {
            Integer authNum = uidAuthNumMap.getOrDefault(uid, NumConsts.ZERO);
            //这个用户的认证数大于3则赋值，否则添加到absentAuthNumUid到下一个间隔天数查询
            if (authNum >= NumConsts.THREE) {
                uidMsgMap.put(uid, String.format(FORMAT, diffDay, authNum));
            } else {
                absentAuthNumUid.add(uid);
            }
        });
        return absentAuthNumUid;
    }

    /**
     * 同行认证总数近期动态
     *
     * @param uid
     * @return java.lang.String   可能返回空串
     * @author  hanjunjun
     * @date 2024/7/9
     **/
    private String fraternityAuthUpdates(Long uid) {
        //日期取前14天
        Date now = new Date();
        DateTime beginOfDay = DateUtil.beginOfDay(now);
        DateTime visitTimeStart = DateUtil.offsetDay(beginOfDay, -NumConsts.FOURTRRN);
        Map<Long, Map<Date, Integer>> uidDateNumMap =
                userLabelAuthRecordService.queryAuthDateNum(Collections.singletonList(uid), LabelTypeEnum.FRATERNITY_AUTH.getCode(),
                        LabelAuthOperateTypeEnum.AUTH.getCode(), visitTimeStart);

        Map<Date, Integer> map = uidDateNumMap.get(uid);
        if (MapUtils.isEmpty(map)) {
            return StringUtils.EMPTY;
        }

        //5、7、14天的数据  按顺序取数量>=3的
        List<Integer> diffDayList = Arrays.asList(NumConsts.FIVE, NumConsts.SEVEN, NumConsts.FOURTRRN);
        for (int diffDay : diffDayList) {
            int authNumSum = this.calculateSumNums(map, diffDay, beginOfDay);
            if (authNumSum >= NumConsts.THREE) {
                return String.format(FORMAT, diffDay, authNumSum);
            }
        }

        return StringUtils.EMPTY;
    }

    /**
     * 求和近x天的认证总数
     *
     * @param authDateNumMap
     * @param diff
     * @param nowBeginOfDay
     * @return int
     * @author  hanjunjun
     * @date 2024/7/9
     **/
    private int calculateSumNums(Map<Date, Integer> authDateNumMap, int diff, Date nowBeginOfDay) {
        AtomicInteger sum = new AtomicInteger();
        authDateNumMap.forEach((authDate, authNum) -> {
            DateTime authDateBeginOfDay = DateUtil.beginOfDay(authDate);
            if (DateUtil.betweenDay(authDateBeginOfDay, nowBeginOfDay, true) <= diff) {
                sum.addAndGet(authNum);
            }
        });

        return sum.get();
    }
}